<?php
namespace app\api\library\traits;

use app\api\model\User\UserModel;
use app\common\extra\Status;
use support\Controller;
use support\Db;
use support\exception\Exception;
use support\Request;

/**
 * Api模块的公共方法
 * Class Api
 * @package app\api\library\traits
 */
class Api extends Controller
{

    protected $model;

    public function __construct()
    {
        parent::__construct();
    }


    /**
     * 错误返回
     * @param string|null $msg
     * @param array $data
     * @param int $code
     * @return \support\Response
     */
    public function error(?string $msg = "fail" , $data = [] , int $code = Status::CODE_NOT_FOUND)
    {
        return parent::error($msg , $data , $code);
    }

    /**
     * 成功返回
     * @param string|null $msg
     * @param array $data
     * @param int $code
     * @return \support\Response
     */
    public function success(?string $msg = "Ok" ,  $data = [] , int $code = Status::CODE_OK)
    {
        return parent::success($msg , $data , $code);
    }


    /**
     * 获取token
     * @param Request $request
     * @return string|null
     */
    public function getToken(Request $request)
    {
        $token = $request->header('token' , '');
        if(empty($token)){
            $token = $request->input('token' , '');
        }
        return $token;
    }

    /**
     * 获取用户信息
     * @param Request $request
     * @param bool $isThrow 是否抛出异常
     * @return array|int|null
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getUserInfo(Request $request , bool $isThrow = true)
    {
        $token = $this->getToken($request);
        $decodeToken = $this->decodeToken($token);
        $uid = $decodeToken['data']['Dat']['id'] ?? null;

        //直接返回用户id
        if($isThrow === false){
            return $uid;
        }

        if(empty($decodeToken) || empty($uid)){
            throw new Exception("请重新登录" , Status::CODE_UNAUTHORIZED);
        }

        //通过uid来查询用户
        $userInfo = Db::name('user')->where('id' , $uid)->find();
        if(empty($userInfo)){
            throw new Exception('未授权，请联系客服。' , Status::CODE_FORBIDDEN);
        }elseif($userInfo['status'] == UserModel::STATUS_OFF){
            throw new Exception('未授权，禁止访问，请联系客服。' , Status::CODE_FORBIDDEN);
        }
        return $userInfo;
    }

    /**
     * 构建where
     * @param Request $request
     * @param array $except
     * @return array[]
     */
    public function buildOption(Request $request , array $except = [])
    {
        $option = $request->input('option' , []);
        $where = [];
        foreach($option as $key => $value){
            /**
             * $value的格式基本为：["key" => "搜索的字段" , "op" => "条件" , "value" => "条件的内容"]
             */
            $op = isset($value['op']) ? strtoupper($value['op']) : "=";
            $searchKey = trim($value['key']);
            $searchValue = $value['value'];
            if(!in_array( $searchKey , $except)){
                $where[] = [$searchKey , $op , $searchValue];
            }
        }
        return [$where];
    }

    /**
     * 获取请求的分页数据
     * @param Request $request
     * @param int $defaultPage
     * @param int $defaultPageSize
     * @return array
     */
    public function buildPage(Request $request , $defaultPage = 1 , $defaultPageSize = 10)
    {
        $page = $request->input('page' , $defaultPage);
        $pageSize = $request->input('pageSize' , $defaultPageSize);
        return [$page , $pageSize];
    }

    /**
     * 获取请求中的排序
     * @param Request $request
     * @return array
     */
    public function buildSort(Request $request , $default = [])
    {
        $res = [];
        $sort = $request->input('sort' , '');
        if(!empty($sort)){
            /**
             * 解析后的格式为 [['order' => '排序字段' , 'type' => 'desc'] , ... ]
             */
            $sort = json_decode( $sort , true);
            foreach($sort as $v){
                $res[] = [
                    $v['order'] => $v['type'] ?? 'desc'
                ];
            }
        }else{
            //检测不到前端的数据，则使用默认排序
            $res = $default;
        }
        return $res;
    }


}